var express = require('express');
var app = express();

var PouchDB = require('pouchdb');
var userDb= new PouchDB('user_db');

var logger = require('morgan');

var fs = require('fs');

var fileType = require('file-type');

var httpsServer = require("./httpserver")(app, 9700);

var sockethttpsServer = require("./httpserver")(app, 9750);

// handler
var registerHandler = require("./handler/register");
var singalingHandler = require("./handler/singaling");
var chatHandler = require("./handler/chat");

const WebSocket = require('ws');
const wss = new WebSocket.Server({
  server: httpsServer,
  clientTracking: true   // to store all connected clients in a set, so you can run forEach on them.
});

let { serverUtils, clientUtils, UserUtils } = require("./utils")({
    WebSocket: WebSocket
});

var users = {}; // key is userID(generated by randomBytes in hex), value is webSocket obj
wss.on('connection', function(ws, req) {
    // ws 3.0 need define upgradeReq by self
    ws.upgradeReq = req;

    var userID = '';

    ws.on('message', msg => {
        if (typeof msg === "string") {
            try{
                var msgObj = JSON.parse(msg);
                // console.log('parsed msg: ', msgObj);
            } catch (e){
                console.log('Oops, unknown msg: ', e)
            }
            switch (msgObj.msgType) {
                case "signaling":
                    singalingHandler(msgObj, userDb, WebSocket, msg, ws, wss, users, serverUtils);
                    break;
                case "register":
                    console.log('parsed msg: ', msgObj);
                    registerHandler(msgObj, userDb, ws, wss, users, serverUtils);
                    // 通知其他客户端注册一下
                    break;
                case "chat":
                    chatHandler(msgObj, userDb, ws, wss, users, serverUtils);
                    break;
                case "firstwoshou":
                    // console.log('------------------------------------');
                    // console.log(msgObj.to);
                    // console.log('------------------------------------');

                    if (msgObj.to) {
                        var toClient = users[msgObj.to.userID];
                        if (toClient && toClient.readyState === WebSocket.OPEN) {                            
                            serverUtils.send(toClient, "duifangzhaoni", { from: msgObj.from });
                        } else {
                            serverUtils.send(ws, "duifangguale", {});
                        }
                    }
                    break;
                case "iamlife": 
                    // console.log('------------------------------------');
                    // console.log(msgObj.to);
                    // console.log('------------------------------------');
                

                    if (msgObj.to) {
                        var toClient = users[msgObj.to.userID];
                        if (toClient && toClient.readyState === WebSocket.OPEN) {                                                    
                            serverUtils.send(toClient, "duifangislife", { from: msgObj.from });
                        } else {
                            serverUtils.send(ws, "duifangguale", {});
                        }
                    } 
                    break;
                default:
                    console.log('Oops. unknown msg: ', msgObj)
            }
        } else {
            // console.log('------------------------------------');
            // console.log(msg instanceof Buffer);
            // console.log('------------------------------------');
            try {
                // var tmpfiletype = fileType(msg);
                // console.log('------------------------------------');
                // console.log(tmpfiletype);
                // console.log('------------------------------------');

                // decode file
                const metalength = parseInt(msg.slice(0, 10).toString().replace(/\*/g, ""));
            
                var c = msg.slice(10, metalength + 20);

                var bs = Buffer.from(c.toString().slice(10), 'base64').toString();

                // console.log('------------------------------------');
                // console.log(c);
                // console.log('------------------------------------');

                // console.log('------------------------------------');
                // console.log(Buffer.from(c.toString().slice(10), 'base64').toString());
                // console.log('------------------------------------');

                // console.log('------------------------------------');
                // console.log(c.toString());
                // console.log('------------------------------------');
                var meta = JSON.parse(bs);                
                var file = msg.slice(metalength + 20);

                console.log('------------------------------------');
                console.log(meta);
                console.log('------------------------------------');
                
                if (meta.network && 
                    meta.network.to && 
                    users[meta.network.to] &&
                    users[meta.network.to].readyState === WebSocket.OPEN) {
                    users[meta.network.to].send(msg);
                }

                // ws.send(msg);
            } catch(e) {
                console.log('------------------------------------');
                console.log(e);
                console.log('------------------------------------');
            }
        }
    });

    ws.on('close', () => {
        clientUtils.notifyClientsRemoveSpecClient(wss.clients, ws);
        console.log("一位失去梦想的群友自己主动退出了房间" + ws.upgradeReq.url + " " + new Date());
        delete users[ ws._uid ]
    });
    ws.on('error', err => {
        console.log('err on ', ws._uid, ': ', err);
        clientUtils.notifyClientsRemoveSpecClient(wss.clients, ws);
        console.log("一位失去梦想的群友因为错误退出了房间" + ws.upgradeReq.url + " " + new Date());
        delete users[ ws._uid ]
    })
});

var io = require("socket.io")(sockethttpsServer);

io.on("connection", function (client) {
    console.log("一位小伙子进入部署");

    client.on("disconnect", function () {
        // 客户端丢失
        console.log("小伙子 还有代码要写呢 disconnect");
    });

    client.on("error", function () {
        // 客户端丢失
        console.log("小伙子 还有代码要写呢 error");
    });
});
